Sesión 8

Curso: Análisis Estadístico de Datos en Salud


Percy Soto-Becerra, M.D., M.Sc(c)

DIS – IETSI, EsSalud

2023-06-21

  https://github.com/psotob91

Reporte Reproducible

Agenda

  1. Reporte Reproducible

  2. tbl_summary() paso a paso

  3. gtsummary: tbl_summary y argumento by =

  4. Buenas y malas prácticas de reporte en investigación

  5. Misceláneas

Reporte Reproducible

¿Cómo hacer que un análisis de datos sea reproducible?


  • No cree la tabla “manualmente”.

  • Genere las tablas con código:

    • Es reproducible.
    • Menos propenso a error de digitación o lapsus calamis.
    • Han habido retracciones de ensayos clínicos por errores de tipeo!!
    • Es más rápido, ahorrarás tiempo!!

R integra el reporte en todo el flujo de trabajo reproducible


Tablas descriptivas


  • En un artículo estas pueden variar entre disciplinas y dependiendo lo qu e se desee comunicar.

  • En investigación en salud, por ejemplo, a la tabla descriptiva menudo se la conoce como tablas tipo 1.

    • Puede haber más de una, no hay reglas, solo buenos o malos criterios para presentar resultados.

    • A veces separan la tabla 1 en Tabla 1 (toda la población) y tabla 2 (comparación de características)

  • Hay muchos paquetes: {flextable}, {gt},{huxtable}, {kableExtra}, {kable}, etc.

  • Sugerimos {gtsummary} para comenzar: https://www.danieldsjoberg.com/gtsummary/

Tablas reproducibles en R


  • Paquetes para construir tablas personalizadas paso a paso:

    • {flextable}
    • {gt}
    • {huxtable}
    • {kable}
    • {kableExtra}
  • Paquetes para construir tablas pre-definidas de manera rápida:

    • {gtsummary}
    • Hay varias más, pero no las tengo mapeadas todas… (en una próxima edición)

Tabla decriptiva reproducible con {gtsummary}


  • Permite crear tablas en formato de revistas biomédicas.

  • Función tbl_summary() para tablas descriptivas univariadas y comparativas (bivariadas)

https://www.danieldsjoberg.com/gtsummary/

Los datos que usaremos


  • Usaremos los datos simulados de un ensayo clínico para evaluar la seguridad de un suplemento en outcomes clinico y fisiologicos de mujeres con menopausia:
id time treat treated age race married2 procedence weight height e2
1 Baseline PLACEBO NA 33 Mestiza Without couple Callao 59.0 1.4 87.30
1 3 months PLACEBO NA 32 Mestiza Without couple Callao 59.9 1.3 210.05
2 Baseline WARMI 6 C/D NA 27 Mestiza Without couple Santa Anita 62.0 1.5 169.01
2 3 months WARMI 6 C/D NA 27 Mestiza Without couple Santa Anita 62.1 1.6 99.91
3 Baseline WARMI 3 C/D NA 25 Mestiza Without couple Callao 62.0 1.6 78.76
3 3 months WARMI 3 C/D NA 25 Mestiza Without couple Callao 60.0 1.6 155.04
  • Las etiquetas de cada variable son:
Variable Label
id ID participant
time Time's measurement
treat Treatment's group
treated Treated
age Age, years
race Race
married2 Marital status, recat
procedence Distrit of procedence
weight Weight, kg
height Height, m
e2 Estradiol

tbl_summary() paso a paso

Agenda

  1. Reporte Reproducible

  2. tbl_summary() paso a paso

  3. gtsummary: tbl_summary y argumento by =

  4. Buenas y malas prácticas de reporte en investigación

  5. Misceláneas

tbl_summary() paso a paso

tbl_summary() básico


  • Seleccionar las variables que desea reportar con función select(), luego usar tbl_summary():
library(gtsummary)
datos %>% 
  select(age, race, married2, e2) %>% 
  tbl_summary()

  • Cuarto tipo de resumenes: continuous, continuos2, categorical y dichotomous

  • Por defecto, los estadísticos son reportadas como mediana (percentil 25, percentil 75) para variables numéricas y n (%) para variables categóricas/dicotómicas.

  • Las variables codificadas como 0 / 1, TRUE / FALSE o Yes / No son tratadas como dicotómicas.

  • Los valores NA se listan como “Unknown

  • Los atributos de etiqueta se imprimen por defecto.

  • Uno puede realizar más personalizaciones a la tabla.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary()

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous")
  )
  • type: Especifica el tipo de variable para el resumen

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      age ~ "{mean} ({sd})", 
      married2 ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(
      c(age, height) ~ "{mean} ({sd})", 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", 
                         "{median} ({p25} - {p75})", 
                         "{min} - {max}"), 
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    )
  ) 
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

    • Usar c() para varias variables.

    • Si queremos reportar más estadísticos en variables numéricas usamos continuous2

      • Podemos ponerle cuantos estadísticos queramos.

      • Podemos tener diferentes combinaciones de estadísticos.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

Personalización del resultado de tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})",
                "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    )
  )
  • type: Especifica el tipo de variable para el resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label: Cambia o personaliza la etiqueta de la variable.

  • digit: Especifica el número de decimales de redondeo.

Reporte de datos perdidos con tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing_text = "Missing data"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

Reporte de datos perdidos con tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "always", missing_text = "Missing data"
  )  
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos.

Reporte de datos perdidos con tbl_summary()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(c(age, height, e2) ~ "continuous2"), 
    statistic = list(
      c(age, height) ~ c("{mean} ({sd})", "{min} - {max}"), 
      c(e2) ~ c("{median} ({p25} - {p75})", "{min} - {max}"),       
      c(married2, treated) ~ "{n}  / {N} ({p}%)"
    ), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    digits = list(
      c(age) ~ 1, c(height, e2) ~ 2, c(married2, treated) ~ 1
    ), 
    missing = "no"
  ) 
  • misisng_text: Permite editar la etiqueta de missing (Unknown por defecto).

  • missing: Por defecto se presentan los datos perdidos solo si la variable los tiene “ifany”.

    • missing = “always” siempre presenta datos perdidos, así la variable no los tenga.
    • missing = “no” nunca presenta datos perdidos, así la variable los tenga.

En resumen: {gtsummary} + fórmulas


Personzalización con bold_() / italicize_()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) 

Personzalización con bold_() / italicize_()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels()
  • bold_labels(): negrita a las etiquetas de las variables

Personzalización con bold_*() / italicize_*()


datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() %>% 
  italicize_levels() 
  • bold_labels(): negrita a las etiquetas de las variables

  • italicize_levels(): cursiva a los niveles (valores) de las variables

Guardar tabla como documento MS Word


  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

Guardar tabla como documento MS Word


  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.

Guardar tabla como documento MS Word


  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)
  • Paso 1: Cargar paquete {flextable}

Guardar tabla como documento MS Word


  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word.
library(flextable)

tabla1 %>% 
  as_flex_table() 

Characteristic

N = 1061

Age, years

33.0 (29.0, 37.0)

Treated with supplement

NA (NA, NA)

Unknown

106

Marital status

With couple

52 (49%)

Without couple

54 (51%)

Height, m

1.50 (1.50, 1.60)

Unknown

3

Estradiol, UI

92 (59, 132)

1Median (IQR); n (%)

  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

Guardar tabla como documento MS Word


  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos %>% 
  select(age, treated, married2, height, e2) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    label = list(
      treated ~ "Treated with supplement", e2 ~ "Estradiol, UI",
      married2 ~ "Marital status"
    ), 
    missing = "ifany"
  ) %>% 
  bold_labels() -> tabla1 

tabla1

  • Luego, al objeto se lo guarda como un archivo de MS Word:
library(flextable)

tabla1 %>% 
  as_flex_table() %>% 
  save_as_docx(path = "Tabla1.docx")
  • Paso 1: Cargar paquete {flextable}

  • Paso 2: Se convierte a objeto de tipo flextable con la función as_flex_table().

  • Paso 3: Se guarda como word con la función save_as_docx()

Guardar tabla como documento MS Word (cont.)


  • El MS Word aparecerá en la carpeta del proyecto:

Guardar tabla como documento MS Word (cont.)


  • Y la tabla en Word lucirá así:

Guardar tabla como documento MS Excel


  • Usamos el paquete {huxtable}
library(huxtable)
  • Con la función as_hux_xlsx convertimos el objeto tbl_summary a un excel con un nombre de archivo que uno defina:
tabla1 %>% 
  as_hux_xlsx(file = "Tabla1.xlsx")
  • La tabla en excel se muestra a continuación:

gtsummary: tbl_summary y argumento by =

Agenda

  1. Reporte Reproducible

  2. tbl_summary() paso a paso

  3. gtsummary: tbl_summary y argumento by =

  4. Buenas y malas prácticas de reporte en investigación

  5. Misceláneas

{gtsummary}: tbl_summary y argumento by =

{gtsummary}: tbl_summary y argumento by =


Se puede usar la función tbl_summary() para comparar variables numéricas según grupos.

bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo)
  • Primero seleccionamos las variables numéricas y la variable de agrupación sexo.
edadtdosis_refuerzoIgG_BasalIgG_Finalsexo
2323399.8 555Femenino
2423241.3 549Masculino
24242414   485
2323413.4 573Femenino
242364.83474Femenino
2624121.7 604Femenino
252018.7 533Femenino
2724110.8 546Femenino
25212417   474Femenino
262393.43558Femenino
28246   378Femenino
2822716.9 547Masculino
27235133   479Masculino
2919664.3 558Femenino
2723520.6 456Femenino
292321.24515Femenino
292365.01534Masculino
2723211.7 572Femenino
2723375.5 535Femenino
2823010.3 559Femenino
2924725.3 527Femenino
312362.78446Femenino
2923720   535Femenino
29198168   580Masculino
302338.18582Femenino
3120651.5 517Femenino
3120614.3 437Femenino
302376.31575Masculino
33242158   599Femenino
312361.11429Masculino
3222771.6 530Femenino
3023528.1 558Femenino
31247139   536Masculino
3223310.8 559Femenino
3321312.3 422Femenino
342325.15540Femenino
3219740.7 290Masculino
3321711.7 530Femenino
321879   570Masculino
3423515.9 533Masculino
3322827.5 481Femenino
3421715.8 459Femenino
332221.84493Femenino
332211.56434Femenino
33190156   585Femenino
322207.26483Femenino
3223638   472Femenino
322356.27525Masculino
322312.69529Masculino
3321839.5 552Masculino
3221813.6 472Femenino
32218191   501Femenino
3421312.8 519Masculino
332374.4 498Femenino
3623516.6 541Masculino
332359.93595Femenino
35220109   573Femenino
3323480.6 616Femenino
332218.88572Femenino
3421880.1 481Femenino
3321231.5 437Femenino
352247.56572Masculino
3423771.8 581Femenino
342322.2 476Masculino
3622158.6 441Femenino
3519673.9 416Femenino
3423416.1 504Femenino
352355.49500Femenino
362367.64509Masculino
35198191   559Femenino
3223336.2 556Femenino
3519114.6 604Masculino
372338.74536Masculino
372233.49568Femenino
3423887.3 519Femenino
36241490   487Masculino
362053.95446Femenino
36232123   414Masculino
3623417.3 592Femenino
3626765.2 454Femenino
36195434   543Femenino
3622025.9 470Femenino
3620435.1 410Femenino
37220422   599Femenino
3721719.8 540Femenino
37234130   376Masculino
372035.75491Femenino
4023619.2 462Masculino
38225122   526Masculino
392376.21575Femenino
37236163   573Femenino
3723589.7 566Femenino
3820235.4 412Femenino
3923571.7 355Femenino
39235327   594Masculino
382053.52528Masculino
4022359.4 502Masculino
392356.76597Femenino
39206137   473Femenino
4019616.1 516Femenino
4222618   515Femenino
4023540.3 468Femenino
41235113   604Masculino
412379.26545Femenino
392320.31530Masculino
41251140   537Femenino
4220518.4 429Femenino
41234191   548Femenino
412053.83524Femenino
44244455   463Femenino
422252.53479Femenino
432347.39531Femenino
4120597.2 474Femenino
4022256.2 481Femenino
4223554.6 550Masculino
442160.32473Femenino
432049.2 424Femenino
42220584   618Femenino
4522011.1 487Femenino
44238115   557Femenino
422072.07327Femenino
4323716.2 490Femenino
4325278.2 552Femenino
4423725.1 451Masculino
452354.9 494Masculino
4320552.5 565Masculino
4423456   532Masculino
4523520.8 486Femenino
442016.72428Femenino
4619128.6 608Femenino
452375.84508Femenino
4621830.1 477Masculino
4421219.1 498Femenino
4520678.2 504Femenino
4420216.9 535Femenino
4623213.7 530Femenino
4523825.6 589Femenino
442324.76427Femenino
472058.08481Femenino
4720915.5 573Femenino
461966.14507Femenino
4624415.8 482Femenino
4724686.4 490Femenino
4720761.2 554Femenino
46214154   416Femenino
4623387.3 507Masculino
4623467.5 575Masculino
4823431.3 468Femenino
48232158   549Masculino
482368.39558Masculino
472050.46523Masculino
4820829   522Femenino
4822911.6 552Femenino
4823111.2 564Femenino
502357.07559Masculino
4920218.4 539Masculino
512283.46390Femenino
49225223   523Masculino
5023611.5 435Femenino
49228371   615Femenino
492057.88531Femenino
5023464.8 495Femenino
492374.49509Femenino
512055.81452Masculino
492332.86500Masculino
5020288.7 560Femenino
5024036.6 545Femenino
5122322.3 594Femenino
5123422.3 509Femenino
5222611   512Femenino
5123170   413Femenino
52198257   587Femenino
512342.9 526Masculino
532024.92542Femenino
52240350   546Femenino
5321913.9 612Femenino
53235152   551Femenino
54193316   441Femenino
552331.99490Masculino
53134105   431Masculino
5423612.3 537Masculino
532038.2 514Femenino
5319649.3 454Femenino
552025.29572Masculino
552336.62519Femenino
552348.85499Femenino
532117.96493Femenino
5623732   538Femenino
551967.17607Femenino
552327.01470Masculino
5420373.1 505Masculino
59235164   563Masculino
55193203   520Femenino
5723573   555Masculino
582024.77468Femenino
592044.98417Femenino
5923339.8 540Masculino
5923642.4 514Femenino
5920625.3 471Femenino
5915927.6 404Femenino
552346.17451Femenino
57220-2.19406Femenino
572320.12459Masculino
592394.09479Masculino
602371.56530Masculino
5722614.2 499Masculino
591947.98485Femenino
582351.48525Femenino
5919728   460Femenino
582341.88463Femenino
57153117   410Femenino
592332.18469Masculino
59157101   367Femenino
59235220   551Femenino
62156404   505Masculino
61218309   598Femenino
5923611.9 538Masculino
59233142   540Masculino
61152528   546Femenino
5915135.9 439Masculino
622057.64521Femenino
59236290   499Masculino
62163458   360Masculino
6119966.5 476Femenino
61155270   523Masculino
622382.08468Femenino
6215587.9 301Femenino
6222142.8 514Femenino
622483.47517Femenino
63157202   521Femenino
6015599.2 412Masculino
6116534.3 354Femenino
6323256.8 555Femenino
62159119   423Femenino
622324.41499Femenino
64154529   544Femenino
652344.23439Femenino
66162518   475Masculino
65211148   389Femenino
6523579   403Femenino
6416154.3 399Masculino
642367.63441Femenino
6517156.1 370Femenino
6416885.4 403Masculino
63181140   452Masculino
6523732.5 564Masculino
67170446   395Masculino
64180131   359Femenino
6617423.7 417Femenino
66225306   568Masculino
6415632.3 382Masculino
67168465   474Masculino
6716478.8 499Femenino
68183195   434Femenino
68166119   489Masculino
682060.75479Femenino
6818435.9 435Femenino
6823412.7 402Masculino
66173451   440Masculino
7024211.8 472Femenino
69185417   349Masculino
7017624.9 333Femenino
6918296   332Masculino
71200270   408Femenino
7018612.4 330Femenino
69184180   408Femenino
7117775.3 466Masculino
71184362   405Masculino
731953.17322Femenino
7219540.6 447Masculino
72186379   557Masculino
7217947.1 510Masculino
7519264.4 386Masculino
73185391   523Femenino
75184102   360Masculino
74171312   468Femenino
7618661.5 397Femenino
7519266.1 471Femenino
7919622.6 309Masculino
7720057.8 363Masculino
7717661.4 442Femenino
7817618   246Masculino
921820.83236Femenino
9418548.7 440Masculino
97206104   442Femenino

{gtsummary}: tbl_summary y argumento by =


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary()
  • Primero seleccionamos las variables numéricas y la variable de agrupación sexo.

  • Si hacemos tbl_summary(), se generará una tabla descriptiva para toda la muestra.

{gtsummary}: tbl_summary y argumento by =


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo)
  • Primero seleccionamos las variables numéricas y la variable de agrupación sexo.

  • Si hacemos tbl_summary(), se generará una tabla descriptiva para toda la muestra.

  • El argumento by() genera una tabla descriptiva con las medidas de resumen por cada grupo.

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo) 

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2")) 
  • type: Especifica el tipo de variable para resumen.

    • Queremos reportar varios estadísticos para edad

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              statistic = list(
                edad ~ c("{mean} ± {sd}", "{median} ({p25}, {p75})")
              )) 
  • type: Especifica el tipo de variable para resumen.

    • Queremos reportar varios estadísticos para edad
  • statistic: Personaliza los estadísticos reportados.

    • Indicamos qué estadísticos queremos reportar para edad.

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              statistic = list(
                edad ~ c("{mean} ± {sd}", "{median} ({p25}, {p75})"), 
                IgG_Basal ~ "{mean} ± {sd}"
              )) 
  • type: Especifica el tipo de variable para resumen.

    • Queremos reportar varios estadísticos para edad
  • statistic: Personaliza los estadísticos reportados.

    • Indicamos qué estadísticos queremos reportar para edad.

    • Queremos reportar media y DE para IgG Basal.

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              statistic = list(
                edad ~ c("{mean} ± {sd}", "{median} ({p25}, {p75})"), 
                IgG_Basal ~ "{mean} ± {sd}"
              ), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              ))
  • type: Especifica el tipo de variable para resumen.

    • Queremos reportar varios estadísticos para edad
  • statistic: Personaliza los estadísticos reportados.

    • Indicamos qué estadísticos queremos reportar para edad.

    • Queremos reportar media y DE para IgG Basal.

  • label Personaliza las etiquetas de variable.

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              statistic = list(
                edad ~ c("{mean} ± {sd}", "{median} ({p25}, {p75})"), 
                IgG_Basal ~ "{mean} ± {sd}"
              ), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              ), 
              digits = list(
                c(IgG_Final, IgG_Basal) ~ 2
              ))
  • type: Especifica el tipo de variable para resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label Personaliza las etiquetas de variable.

  • digits: Controla el número de decimales de redondeo.

    • Permitir que IgG (basal y final) se reporten con solo 2 decimales.

Personalizar tbl_summary() paso a paso


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              statistic = list(
                edad ~ c("{mean} ± {sd}", "{median} ({p25}, {p75})"), 
                IgG_Basal ~ "{mean} ± {sd}"
              ), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              ), 
              digits = list(
                c(IgG_Final, IgG_Basal) ~ 2, 
                edad ~ c(1, 2, 1, 2)
              )) 
  • type: Especifica el tipo de variable para resumen.

  • statistic: Personaliza los estadísticos reportados.

  • label Personaliza las etiquetas de variable.

  • digits: Controla el número de decimales de redondeo.

    • Edad que se reporte con 1 decimal la media y media y 2 decimales la SD y el IQR.

Más personalización de tbl_summary() con add_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              ))

Más personalización de tbl_summary() con add_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) %>% 
  add_overall()
  • add_overall: Agrega una columna con el resumen de características para toda la población de estudio.

Más personalización de tbl_summary() con add_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) %>% 
  add_overall() %>% 
  add_n()
  • add_overall: Agrega una columna con el resumen de características para toda la población de estudio.

  • add_n(): Agrega una columna con el tamaño de muestra efectivo (excluyendo los datos perdidos)

Más personalización de tbl_summary() con modify_()


  • Podemos modificar el nombre de las cabeceras, pero primero hay que saber cómo están guardadas.

  • Creamos la tabla cruda y la guardamos con un nombre:

bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) -> tabla

tabla

Más personalización de tbl_summary() con modify_()


  • Podemos modificar el nombre de las cabeceras, pero primero hay que saber cómo están guardadas.

  • Creamos la tabla cruda y la guardamos con un nombre:

bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) -> tabla

tabla
  • Luego, consultamos los nombres de cabeceras internos que tiene el objeto tbl_summary:
show_header_names(tabla)



Column Name   Column Header         
------------  ----------------------
label         **Characteristic**    
stat_1        **Femenino**, N = 189 
stat_2        **Masculino**, N = 95 

  • Podemos editar los nombres de las cabeceras llamándolos como label, stat_1 y stat_2.

Más personalización de tbl_summary() con modify_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) 
  • modify_header(): Edita los nombres de las cabeceras.

Más personalización de tbl_summary() con modify_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) %>% 
  modify_header(
    label ~ "Variables", 
    stat_1 ~ "Female", 
    stat_2 ~ "Male"
  )
  • modify_header(): Edita los nombres de las cabeceras.

Más personalización de tbl_summary() con modify_()


bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) %>% 
  modify_header(
    label ~ "Variables", 
    stat_1 ~ "Female", 
    stat_2 ~ "Male"
  )
  • modify_header(): Edita los nombres de las cabeceras.

    • Podemos editar el contenido de estas con {}

      • Por ejemplo, poner “n = {n}”

Más personalización de tbl_summary() con modify_()


:::: {.columns}

bd_inmuno %>% 
  select(edad, tdosis_refuerzo, IgG_Basal, IgG_Final, sexo) %>% 
  tbl_summary(by = sexo, 
              type = list(edad ~ "continuous2"), 
              label = list(
                edad ~ "Age, years", 
                tdosis_refuerzo ~ "Time between second and third dose", 
                IgG_Basal ~ "IgG pre booster", 
                IgG_Final ~ "IgG post booster"
              )) %>% 
  modify_header(
    label ~ "Variables", 
    stat_1 ~ "Female (n = {n})", 
    stat_2 ~ "Male (n = {n})"
  )  
  • modify_header(): Edita los nombres de las cabeceras.

    • Podemos editar el contenido de estas con {}

      • Por ejemplo, poner “n = {n}”

::: {.column width=‘50%’}

Buenas y malas prácticas de reporte en investigación

Agenda

  1. Reporte Reproducible

  2. tbl_summary() paso a paso

  3. gtsummary: tbl_summary y argumento by =

  4. Buenas y malas prácticas de reporte en investigación

  5. Misceláneas

Buenas y malas prácticas de reporte en investigación

Recomendaciones de reporte

  • No reporte valores p innecesarios, que no respondan sus preguntas de investigación pre-definidas.

  • Es una mala práctica reportar tablas comparativas descriptivas con valores p. Lamentablemente es muy difundida.

  • Varias guías, comenzando por STROBE (para observacionales) y CONSORT (para ensayos clínicos) explícitamente recomiendan en contra de reportar estas tablas. Solo haga una comparación descriptiva de los resultados de la tabla.

gtsummary and p-values

  • Se puede agregar el valor p en las tablas de gtsummary:
library(gtsummary)
datos %>%
  dplyr::select(treat, age, race, married2, weight, height, e2) %>% 
  tbl_summary(
    by = treat
  ) %>%  
  add_p()
Characteristic PLACEBO, N = 341 WARMI 3 C/D, N = 341 WARMI 6 C/D, N = 381 p-value2
Age, years 34.0 (31.3, 37.0) 31.0 (27.0, 38.0) 35.0 (30.0, 37.0) 0.8
Race
    Mestiza 34 (100%) 34 (100%) 38 (100%)
Marital status, recat 0.4
    With couple 16 (47%) 14 (41%) 22 (58%)
    Without couple 18 (53%) 20 (59%) 16 (42%)
Weight, kg 59 (56, 65) 60 (56, 65) 61 (54, 66) >0.9
    Unknown 1 1 1
Height, m 0.2
    1.3 1 (3.0%) 0 (0%) 0 (0%)
    1.4 5 (15%) 1 (3.0%) 6 (16%)
    1.5 13 (39%) 22 (67%) 17 (46%)
    1.6 10 (30%) 9 (27%) 9 (24%)
    1.7 4 (12%) 1 (3.0%) 5 (14%)
    Unknown 1 1 1
Estradiol 90 (50, 129) 95 (74, 128) 96 (61, 147) 0.6
1 Median (IQR); n (%)
2 Kruskal-Wallis rank sum test; Pearson’s Chi-squared test; Fisher’s exact test

¿Qué dice STROBE?

  • La guía “Strengthening the reporting of observational studies in epidemiology (STROBE) statement” da algunas recomendaciones para tablas tipo 1:

¿Qué dice STROBE?

  • STROBE recomienda en contra de reportar valores p en las tablas descriptivas!!
https://journals.lww.com/epidem/Fulltext/2007/11000/Strengthening_the_Reporting_of_Observational.28.aspx
  • Lamentablemente sigue siendo una mala práctica muy difundida. Evitemos esta mala práctica.

¿Y valores p en la Tabla 11 de ensayos clínicos?

  • El “Consolidated Standards of Reporting Trials (CONSORT)” recomienda no usar valores p ni métodos de inferencia estadística en la Tabla 1.

  • Evaluar el “balance” y la “adecuada” asignación aleatoria en la Tabla 1 de un ensayo clínico es conocido como: “Falacia de la tabla 1”.

  • Para más información revise el siguiente artículo: https://www.bmj.com/content/340/bmj.c869

Misceláneas

Agenda

  1. Reporte Reproducible

  2. tbl_summary() paso a paso

  3. gtsummary: tbl_summary y argumento by =

  4. Buenas y malas prácticas de reporte en investigación

  5. Misceláneas

{gtsummary}: Misceláneas

Otras formas de imprimir tablas

  • Tablas con kable() y kableExtra() de paquete {knitr}.

  • Tablas de {gt} y {flextable}.

Reproducibilidad y gráficos

  • Crear gráficos de alta calidad con ggplot2

  • Guardar gráficos especificando sus parámetros con ggsave

  • Ensamblar gráficos con {patchwork}

  • Imprimir imágenes en Quarto

Superpoderes de Quarto

  • Código dentro de texto.

  • Información extra sobre Quarto

  • Configuraciones básicas adicionales.

  • Temas de Quarto

Hagamos una pausa


Tomemos un descanso de 5 minutos

Estire las piernas

Deje de ver las pantallas

… cualquier , las del celular también.

05:00

¡Gracias!
¿Preguntas?




@psotob91

https://github.com/psotob91

percys1991@gmail.com